<template>
	<view class="yb-infinite-slider yb-flex"
	:id="customIdSync"
	:class="customClassSync"
	:style="customStyleSync">
		<swiper
		@touchstart="isTouch = true"
		@touchend="isTouch = false"
		:current="swiperCurrent"
		@change="onCurrentChange"
		@transition="onTransition"
		class="yb-flex yb-flex-1"
		circular
		vertical
		skip-hidden-item-layout
		:indicator-dots="false"
		:autoplay="false"
		:duration="500">
			<swiper-item v-for="(item, index) in showlist" :key="index">
				<template v-if="item.type == 'prevLoading'">
					<view class="yb-flex yb-flex-1 yb-align-center yb-justify-center">
						<yb-loading :visible="isPulldown" text="加载中" type="3" :color="pulldownOptionsSync.color"></yb-loading>
						<template v-if="!isPulldown">
							<template v-if="pulldownStatus == 'fail'">
								<yb-icon custom-style="margin-bottom: 20rpx" name="fork-circle" :size="60" :color="pulldownOptionsSync.color"></yb-icon>
								<text class="yb-infinite-slider-tip-text" :style="{color: pulldownOptionsSync.color}">{{pulldownOptionsSync.failText}}</text>
								<yb-tap @click="onPulldown">
									<yb-tag custom-class="yb-infinite-slider-tip-btn" :options="{
										bgColor: pulldownOptionsSync.color,
										size: 28
									}" plain value="点此重试"></yb-tag>
								</yb-tap>
							</template>
							<template v-else>
								<yb-icon custom-style="margin-bottom: 20rpx" name="hook-circle" :size="60" :color="pulldownOptionsSync.color"></yb-icon>
								<text class="yb-infinite-slider-tip-text" :style="{color: pulldownOptionsSync.color}">已经到最顶部了</text>
								<yb-tap @click="onPulldown">
									<yb-tag custom-class="yb-infinite-slider-tip-btn" :options="{
										bgColor: pulldownOptionsSync.color,
										size: 28
									}" plain :value="pulldownOptionsSync.defaultText"></yb-tag>
								</yb-tap>
							</template>
							<text class="yb-infinite-slider-tip-text" :style="{color: pulldownOptionsSync.color}">继续上滑到最底部</text>
						</template>
					</view>
				</template>
				<template v-else-if="item.type == 'nextLoading'">
					<view class="yb-flex yb-flex-1 yb-align-center yb-justify-center">
						<yb-loading :visible="isLoadmore" text="加载中" type="3" :color="loadmoreOptionsSync.color"></yb-loading>
						<template v-if="!isLoadmore">
							<template v-if="loadmoreStatus == 'fail'">
								<yb-icon custom-style="margin-bottom: 20rpx" name="fork-circle" :size="60" :color="loadmoreOptionsSync.color"></yb-icon>
								<text class="yb-infinite-slider-tip-text" :style="{color: loadmoreOptionsSync.color}">{{loadmoreOptionsSync.failText}}</text>
								<yb-tap @click="onCallback">
									<yb-tag custom-class="yb-infinite-slider-tip-btn" :options="{
										bgColor: loadmoreOptionsSync.color,
										size: 28
									}" plain value="点此重试"></yb-tag>
								</yb-tap>
							</template>
							<template v-else-if="loadmoreStatus == 'end'">
								<yb-icon custom-style="margin-bottom: 20rpx" name="hook-circle" :size="60" :color="loadmoreOptionsSync.color"></yb-icon>
								<text class="yb-infinite-slider-tip-text" :style="{color: loadmoreOptionsSync.color}">{{loadmoreOptionsSync.endText}}</text>
								<yb-tap @click="onPulldown">
									<yb-tag custom-class="yb-infinite-slider-tip-btn" :options="{
										bgColor: loadmoreOptionsSync.color,
										size: 28
									}" plain :value="pulldownOptionsSync.defaultText"></yb-tag>
								</yb-tap>
							</template>
							<template v-else>
								<yb-icon custom-style="margin-bottom: 20rpx" name="hook-circle" :size="60" :color="loadmoreOptionsSync.color"></yb-icon>
								<text class="yb-infinite-slider-tip-text" :style="{color: loadmoreOptionsSync.color}">已经到最底部了</text>
								<yb-tap @click="onLoadmore">
									<yb-tag custom-class="yb-infinite-slider-tip-btn" :options="{
										bgColor: loadmoreOptionsSync.color,
										size: 28
									}" plain :value="loadmoreOptionsSync.defaultText"></yb-tag>
								</yb-tap>
							</template>
							<text class="yb-infinite-slider-tip-text" :style="{color: loadmoreOptionsSync.color}">继续下滑到最顶部</text>
						</template>
					</view>
				</template>
				<template v-else>
					<slot :name="item.currentIndex"></slot>
				</template>
			</swiper-item>
		</swiper>
		<view class="yb-infinite-slider-mask" v-if="isPulldown" @touchmove.stop.prevent></view>
	</view>
</template>

<script>
	import Util from '../../js_sdk/util.js'
	import ComponentMixin from '../../js_sdk/componentMixin.js'
	export default {
		name: 'YbInfiniteSlider',//无限滑动
		mixins: [ComponentMixin],
		props: {
			pulldown: {
				type: [Boolean, Object],
				default: true
			},
			loadmore: {
				type: [Boolean, Object],
				default: false
			}
		},
		computed: {
			pulldownOptionsSync () {
				return Object.assign({}, {
					show: false,
					//默认文本
					defaultText: '点此刷新数据',
					//刷新中的提示文本
					refreshingText: '正在刷新',
					//刷新成功的提示文本
					successText: '刷新成功',
					//刷新失败的提示文本
					failText: '刷新数据失败',
					//文本颜色
					color: '#333333'
				}, Util.typeof(this.pulldown) == 'Object' ? this.pulldown : Util.typeof(this.pulldown) == 'Boolean' ? { show: this.pulldown } : {})
			},
			loadmoreOptionsSync () {
				return Object.assign({}, {
					//是否展示加载更多
					show: false,
					//默认文本
					defaultText: '点此获取更多数据',
					//刷新中的提示文本
					refreshingText: '正在获取',
					//刷新成功的文本
					successText: '获取数据成功',
					//刷新失败的提示文本
					failText: '获取数据失败',
					//数据全部加载完毕的提示文本
					endText: '数据加载完毕',
					//文本颜色
					color: '#333333'
					//刷新完成后的隐藏周期
				}, Util.typeof(this.loadmore) == 'Object' ? this.loadmore : Util.typeof(this.loadmore) == 'Boolean' ? { show: this.loadmore } : {})
			}
		},
		data () {
			return {
				swiperCurrent: 0,
				currentIndex: 0,
				nextCurrentIndex: 0,
				isTouch: false,
				isLoad: false,
				list: [],
				showlist: [],
				isPulldown: false,
				isLoadmore: false,
				pulldownStatus: '',
				loadmoreStatus: ''
			}
		},
		methods: {
			onCurrentChange (e) {
				if ( this.nextCurrentIndex > this.currentIndex ) {
					this.$set(this.showlist, this.swiperCurrent, {type: 'prevLoading'})
					this.currentIndex = this.nextCurrentIndex
				} else if ( this.nextCurrentIndex < this.currentIndex ) {
					this.$set(this.showlist, this.swiperCurrent, {type: 'nextLoading'})
					this.currentIndex = this.nextCurrentIndex
				}
				this.swiperCurrent = e.detail.current
				this.$emit('change', {
					detail: {
						current: this.currentIndex,
						data: this.showlist[this.currentIndex]
					}
				})
				if ( this.currentIndex == this.list.length - 1 && !this.loadmoreStatus != 'end' && this.loadmoreOptionsSync.show ) {
					this.onLoadmore()
				}
			},
			onTransition (e) {
				if ( this.isTouch ) {
					if ( e.detail.dy > 0 ) {
						let nextCurrent = this.swiperCurrent + 1 > 2 ? 0 : this.swiperCurrent + 1
						if ( (this.currentIndex + 1 < this.list.length) || !this.loadmoreOptionsSync.show ) {
							this.nextCurrentIndex = this.currentIndex + 1 > this.list.length-1 ? 0 : this.currentIndex + 1
							this.$set(this.showlist, nextCurrent, Object.assign({}, this.list[this.nextCurrentIndex], {
								currentIndex: this.nextCurrentIndex
							}))
						} else if ( this.currentIndex == this.list.length ) {
							this.nextCurrentIndex = 0
							this.$set(this.showlist, nextCurrent, Object.assign({}, this.list[this.nextCurrentIndex], {
								currentIndex: this.nextCurrentIndex
							}))
						} else {
							this.nextCurrentIndex = this.list.length
							this.$set(this.showlist, nextCurrent, {
								type: 'nextLoading'
							})
						}
					} else if ( e.detail.dy < 0 ) {
						let nextCurrent = this.swiperCurrent - 1 < 0 ? 2 : this.swiperCurrent - 1
						if ( (this.currentIndex - 1 >= 0) || !this.pulldownOptionsSync.show ) {
							this.nextCurrentIndex = this.currentIndex - 1 < 0 ? this.list.length-1 : this.currentIndex - 1
							this.$set(this.showlist, nextCurrent, Object.assign({}, this.list[this.nextCurrentIndex], {
								currentIndex: this.nextCurrentIndex
							}))
						} else if ( this.currentIndex == -1 ) {
							this.nextCurrentIndex = this.list.length - 1
							this.$set(this.showlist, nextCurrent, Object.assign({}, this.list[this.nextCurrentIndex], {
								currentIndex: this.nextCurrentIndex
							}))
						} else {
							this.nextCurrentIndex = -1
							this.$set(this.showlist, nextCurrent, {
								type: 'prevLoading'
							})
						}
					} else {
						let nextCurrent = this.swiperCurrent
						this.nextCurrentIndex = this.currentIndex
						this.$set(this.showlist, nextCurrent, Object.assign({}, this.list[this.nextCurrentIndex], {
							currentIndex: this.nextCurrentIndex
						}))
					}
				}
			},
			init (data) {
				this.isPulldown = true
				this.showlist = [{
					type: 'prevLoading'
				}]
				this.list = []
				this.$nextTick(function () {
					this.list = data
					this.showlist = [{
						type: 'prevLoading'
					},Object.assign({}, this.list[0], {
						currentIndex: 0
					}),{
						type: 'nextLloading'
					}]
					this.$nextTick(function () {
						setTimeout(() => {
							this.swiperCurrent = 1
						}, 100)
					})
				})
			},
			refresh () {
				this.onPulldown()
			},
			onPulldown () {
				if (!this.isPulldown ) {
					this.swiperCurrent = 0
					this.showlist = [{
						type: 'prevLoading'
					}]
					this.list = []
					this.currentIndex = 0
					this.nextCurrentIndex = 0
					this.isPulldown = true
					this.$emit('pulldown', res => {
						if ( res.status == 'success' ) {
							this.list = res.data.list
							this.showlist = [{
								type: 'prevLoading'
							},Object.assign({}, this.list[0], {
								currentIndex: 0
							}),{
								type: 'nextLloading'
							}]
							this.$nextTick(function () {
								setTimeout(() => {
									this.swiperCurrent = 1
								}, 100)
							})
						} else {
							this.showlist = [{
								type: 'prevLoading'
							}]
							this.$nextTick(function () {
								setTimeout(() => {
									this.swiperCurrent = 0
								}, 100)
							})
						}
						this.pulldownStatus = res.status
						this.isPulldown = false
					})
				}
			},
			onLoadmore () {
				if ( !this.isLoadmore ) {
					this.isLoadmore = true
					this.$emit('loadmore', res => {
						if ( res.status == 'success' ) {
							if ( this.currentIndex == this.list.length && res.data.list.length > 0 ) {
								this.$set(this.showlist, this.swiperCurrent, Object.assign({}, res.data.list[0], {
									currentIndex: this.currentIndex
								}))
							}
							this.list = this.list.concat(res.data.list)
						}
						this.loadmoreStatus = res.status
						this.isLoadmore = false
					})
				}
			},
			resetLoadmore () {
				this.loadmoreStatus = ''
			},
			setLoadmoreEnd () {
				this.loadmoreStatus = 'end'
			},
			setLoadmoreSuccess () {
				this.loadmoreStatus = 'success'
			},
			setLoadmoreFail () {
				this.loadmoreStatus = 'fail'
			}
		}
	}
</script>

<style>
	.yb-infinite-slider {
		position: relative;
	}
	.yb-infinite-slider-mask {
		position: absolute;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
	}
	.yb-infinite-slider-tip-text {
		font-size: 28rpx;
		margin: 0 100rpx;
		text-align: center;
	}
	.yb-infinite-slider-tip-btn {
		margin: 20rpx 0;
	}
</style>